package com.baiytfp.hf.HFDataExchange.common.utils;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;

import com.baiytfp.hf.baiytfp.common.util.ClassUtil;
import com.baiytfp.hf.baiytfp.common.util.PropUtil;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;

public class FreemarkerUtil {
	private Configuration freemarker_cfg = null;
	private Template t = null;
	private static final String ENCODING = "UTF-8";

	public FreemarkerUtil() {

	}
	
	public FreemarkerUtil(ServletContext servletContext, String filePath, String templatePath) throws Exception {
		freemarker_cfg = getFreeMarkerCFG(servletContext, templatePath);
		t = getTemplate(filePath);
	}
	
	public FreemarkerUtil(ServletContext servletContext, String filePath, String templatePath, String propertiesFile) throws Exception {
		freemarker_cfg = getFreeMarkerCFG(servletContext, templatePath, propertiesFile);
		t = getTemplate(filePath);
	}
	
	public FreemarkerUtil(ServletConfig servletConfig, String filePath, String templatePath) throws Exception {
		freemarker_cfg = getFreeMarkerCFG(servletConfig, templatePath);
		t = getTemplate(filePath);
	}
	
	public FreemarkerUtil(ServletConfig servletConfig, String filePath, String templatePath, String propertiesFile) throws Exception {
		freemarker_cfg = getFreeMarkerCFG(servletConfig.getServletContext(), templatePath, propertiesFile);
		t = getTemplate(filePath);
	}

	/**
	 * 获取freemarker的配置. freemarker本身支持classpath,目录和从ServletContext获取.
	 */
	public Configuration getFreeMarkerCFG(ServletConfig servletConfig, String templatePath) {
		return getFreeMarkerCFG(servletConfig.getServletContext(), templatePath);
	}
	public Configuration getFreeMarkerCFG(ServletContext servletContext,
			String templatePath) {
		if (null == freemarker_cfg) {
			// 初始化
			freemarker_cfg = new Configuration();
			freemarker_cfg.setEncoding(Locale.CHINA, ENCODING); // 防止乱码(UTF8使用)
			// 设置模板路径
			freemarker_cfg.setServletContextForTemplateLoading(servletContext, templatePath);
			
			//读取 freemaker.properties 的配置参数
			PropUtil propUtil = new PropUtil(ClassUtil.getDefaultClassLoader().getResourceAsStream("/freemaker.properties"));
			Iterator<Entry<Object, Object>> it = propUtil.getProperties().entrySet().iterator();
	        while (it.hasNext()) {
	            Entry entry = it.next();
	            
	            try{
	            	freemarker_cfg.setSetting(entry.getKey() + "", entry.getValue() + "");
	            }catch(Exception ex){
	            	// nothing
	            }
	        }
		}

		return freemarker_cfg;
	}
	public Configuration getFreeMarkerCFG(ServletContext servletContext,
			String templatePath, String propertiesFile) {
		if (null == freemarker_cfg) {
			// 初始化
			freemarker_cfg = new Configuration();
			freemarker_cfg.setEncoding(Locale.CHINA, ENCODING); // 防止乱码(UTF8使用)
			// 设置模板路径
			freemarker_cfg.setServletContextForTemplateLoading(servletContext, templatePath);
			
			//读取 freemaker.properties 的配置参数
			PropUtil propUtil = new PropUtil(ClassUtil.getDefaultClassLoader().getResourceAsStream(propertiesFile));
			Iterator<Entry<Object, Object>> it = propUtil.getProperties().entrySet().iterator();
	        while (it.hasNext()) {
	            Entry entry = it.next();
	            
	            try{
	            	freemarker_cfg.setSetting(entry.getKey() + "", entry.getValue() + "");
	            }catch(Exception ex){
	            	// nothing
	            }
	        }
		}

		return freemarker_cfg;
	}

	/**
	 * 取得模板
	 */
	public Template getTemplate(String filePath) throws Exception {
		if (null == t) {
			try {
				t = freemarker_cfg.getTemplate(filePath);
			} catch (Exception e) {
				throw e;
			}
		}

		return t;
	}

	/**
	 * 输出html页面
	 */
	public void printPage(HttpServletResponse response, Map root)
			throws Exception {
		response.setHeader("Cache-Control", "no-cache");
		response.setContentType("text/html; charset=" + ENCODING);
		PrintWriter out = null;
		try {
			out = response.getWriter();
			t.process(root, out);// 用模板来开发servlet可以只在代码里面加入动态的数据
		} catch (TemplateException e) {
			throw new ServletException("处理Template模版中出现错误", e);
		} catch (Exception e) {
			throw e;
		} finally {
			if (out != null) {
				out.close();
			}
		}
	}

	public String getPageString(Map root) throws Exception {
		
		String result = "";
		
		Writer out = null;
		
		try {
			out = new StringWriter(2048); 
			t.process(root, out);// 用模板来开发servlet可以只在代码里面加入动态的数据
			
			result = out.toString();
		} catch (TemplateException e) {
			throw new ServletException("处理Template模版中出现错误", e);
		} catch (Exception e) {
			throw e;
		} finally {
			if (out != null) {
				out.close();
			}
		}
		
		return result;
	}

	/**
	 * 生成静态文件.
	 * 
	 * @param templateFileName
	 *            模板文件名,相对htmlskin路径,例如"/tpxw/view.ftl"
	 * @param propMap
	 *            用于处理模板的属性Object映射
	 * @param htmlFilePath
	 *            要生成的静态文件的路径,相对设置中的根路径,例如 "/tpxw/1/2005/4/"
	 * @param htmlFileName
	 *            要生成的文件名,例如 "1.htm"
	 */
	/*
	public boolean geneHtmlFile(String templateFileName, Map propMap,
			String htmlFilePath, String htmlFileName,
			ServletContext servletContext) {
		// @todo 从配置中取得要静态文件存放的根路径:需要改为自己的属性类调用
		String sRootDir = "e:/webtest/htmlfile";

		try {
			Template t = getFreeMarkerCFG(servletContext).getTemplate(
					templateFileName);

			// 如果根路径存在,则递归创建子目录
			creatDirs(sRootDir, htmlFilePath);

			File afile = new File(sRootDir + "/" + htmlFilePath + "/"
					+ htmlFileName);

			Writer out = new BufferedWriter(new OutputStreamWriter(
					new FileOutputStream(afile)));

			t.process(propMap, out);
		} catch (TemplateException e) {
			System.out.println("Error while processing FreeMarker template "
					+ templateFileName);
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			System.out.println("Error while generate Static Html File "
					+ htmlFileName);
			e.printStackTrace();
			return false;
		}

		return true;
	}
	*/
	
	/**
	 * 创建多级目录
	 * 
	 * @param aParentDir
	 *            String
	 * @param aSubDir
	 *            以 / 开头
	 * @return boolean 是否成功
	 */
	public static boolean creatDirs(String aParentDir, String aSubDir) {
		File aFile = new File(aParentDir);
		if (aFile.exists()) {
			File aSubFile = new File(aParentDir + aSubDir);
			if (!aSubFile.exists()) {
				return aSubFile.mkdirs();
			} else {
				return true;
			}
		} else {
			return false;
		}
	}
}
